<html><head><title>BasicForm.js</title><link rel="stylesheet" type="text/css" href="../resources/style.css" media="screen"/></head><body><h1>BasicForm.js</h1><pre class="highlighted"><code><i>/**
 * @class Ext.form.BasicForm
 * @extends Ext.util.Observable
 * Supplies the functionality to <b>do</b> &quot;actions&quot; on forms and initialize Ext.form.Field types on existing markup.
 * @constructor
 * @param {String/HTMLElement/Ext.Element} el The form element or its id
 * @param {Object} config Configuration options
 */</i>
Ext.form.BasicForm = <b>function</b>(el, config){
    Ext.apply(<b>this</b>, config);
    <i>/*
     * The Ext.form.Field items <b>in</b> this form.
     * @type MixedCollection
     */</i>
    <b>this</b>.items = <b>new</b> Ext.util.MixedCollection(false, <b>function</b>(o){
        <b>return</b> o.id || (o.id = Ext.id());
    });
    <b>this</b>.addEvents({
        <i>/**
         * @event beforeaction
         * Fires before any action is performed. Return false to cancel the action.
         * @param {Form} <b>this</b>
         * @param {Action} action The action to be performed
         */</i>
        beforeaction: true,
        <i>/**
         * @event actionfailed
         * Fires when an action fails.
         * @param {Form} <b>this</b>
         * @param {Action} action The action that failed
         */</i>
        actionfailed : true,
        <i>/**
         * @event actioncomplete
         * Fires when an action is completed.
         * @param {Form} <b>this</b>
         * @param {Action} action The action that completed
         */</i>
        actioncomplete : true
    });
    <b>if</b>(el){
        <b>this</b>.initEl(el);
    }
    Ext.form.BasicForm.superclass.constructor.call(<b>this</b>);
};

Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
    <i>/**
     * @cfg {String} method
     * The request method to use (GET or POST) <b>for</b> form actions <b>if</b> one isn't supplied <b>in</b> the action options.
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {DataReader} reader
     * An Ext.data.DataReader (e.g. {@link Ext.data.XmlReader}) to be used to read data when executing &quot;load&quot; actions.
     * This is optional as there is built-<b>in</b> support <b>for</b> processing JSON.
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {DataReader} errorReader
     * An Ext.data.DataReader (e.g. {@link Ext.data.XmlReader}) to be used to read data when reading validation errors on &quot;submit&quot; actions.
     * This is completely optional as there is built-<b>in</b> support <b>for</b> processing JSON.
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {String} url
     * The URL to use <b>for</b> form actions <b>if</b> one isn't supplied <b>in</b> the action options.
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {Boolean} fileUpload
     * Set to true <b>if</b> this form is a file upload.
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {Object} baseParams
     * Parameters to pass <b>with</b> all requests. e.g. baseParams: {id: <em>'123'</em>, foo: <em>'bar'</em>}.
     */</i>
<i>// holder</i>
<i>/***
     * @cfg {Number} timeout Timeout <b>for</b> form actions <b>in</b> seconds (<b>default</b> is 30 seconds).
     */</i>
    timeout: 30,

    <i>// private</i>
    activeAction : null,

    <i>/**
     * @cfg {Boolean} trackResetOnLoad If set to true, form.reset() resets to the last loaded
     * or setValues() data instead of when the form was first created.
     */</i>
    trackResetOnLoad : false,

    <i>/**
     * By <b>default</b> wait messages are displayed <b>with</b> Ext.MessageBox.wait. You can target a specific
     * element by passing it or its id or mask the form itself by passing <b>in</b> true.
     * @type Mixed
     */</i>
    waitMsgTarget : undefined,

    <i>// private</i>
    initEl : <b>function</b>(el){
        <b>this</b>.el = Ext.get(el);
        <b>this</b>.id = <b>this</b>.el.id || Ext.id();
        <b>this</b>.el.on(<em>'submit'</em>, <b>this</b>.onSubmit, <b>this</b>);
        <b>this</b>.el.addClass(<em>'x-form'</em>);
    },

    <i>// private</i>
    onSubmit : <b>function</b>(e){
        e.stopEvent();
    },

    <i>/**
     * Returns true <b>if</b> client-side validation on the form is successful.
     * @<b>return</b> Boolean
     */</i>
    isValid : <b>function</b>(){
        <b>var</b> valid = true;
        <b>this</b>.items.each(<b>function</b>(f){
           <b>if</b>(!f.validate()){
               valid = false;
           }
        });
        <b>return</b> valid;
    },

    <i>/**
     * Returns true <b>if</b> any fields <b>in</b> this form have changed since their original load.
     * @<b>return</b> Boolean
     */</i>
    isDirty : <b>function</b>(){
        <b>var</b> dirty = false;
        <b>this</b>.items.each(<b>function</b>(f){
           <b>if</b>(f.isDirty()){
               dirty = true;
               <b>return</b> false;
           }
        });
        <b>return</b> dirty;
    },

    <i>/**
     * Performs a predefined action (submit or load) or custom actions you define on <b>this</b> form.
     * @param {String} actionName The name of the action type
     * @param {Object} options (optional) The options to pass to the action.  All of the config options listed
     * below are supported by both the submit and load actions unless otherwise noted (custom actions could also
     * accept other config options):
     * &lt;pre&gt;
Property          Type             Description
----------------  ---------------  ----------------------------------------------------------------------------------
url               String           The url <b>for</b> the action (defaults to the form's url)
method            String           The form method to use (defaults to the form's method, or POST <b>if</b> not defined)
params            String/Object    The params to pass (defaults to the form's baseParams, or none <b>if</b> not defined)
clientValidation  Boolean          Applies to submit only.  Pass true to call form.isValid() prior to posting to
                                   validate the form on the client (defaults to false)
     * &lt;/pre&gt;
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    doAction : <b>function</b>(action, options){
        <b>if</b>(typeof action == <em>'string'</em>){
            action = <b>new</b> Ext.form.Action.ACTION_TYPES[action](<b>this</b>, options);
        }
        <b>if</b>(this.fireEvent(<em>'beforeaction'</em>, <b>this</b>, action) !== false){
            <b>this</b>.beforeAction(action);
            action.run.defer(100, action);
        }
        <b>return</b> this;
    },

    <i>/**
     * Shortcut to <b>do</b> a submit action.
     * @param {Object} options The options to pass to the action (see {@link #doAction} <b>for</b> details)
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    submit : <b>function</b>(options){
        <b>this</b>.doAction(<em>'submit'</em>, options);
        <b>return</b> this;
    },

    <i>/**
     * Shortcut to <b>do</b> a load action.
     * @param {Object} options The options to pass to the action (see {@link #doAction} <b>for</b> details)
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    load : <b>function</b>(options){
        <b>this</b>.doAction(<em>'load'</em>, options);
        <b>return</b> this;
    },

    <i>/**
     * Persists the values <b>in</b> this form into the passed Ext.data.Record object <b>in</b> a beginEdit/endEdit block.
     * @param {Record} record The record to edit
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    updateRecord : <b>function</b>(record){
        record.beginEdit();
        <b>var</b> fs = record.fields;
        fs.each(<b>function</b>(f){
            <b>var</b> field = <b>this</b>.findField(f.name);
            <b>if</b>(field){
                record.set(f.name, field.getValue());
            }
        }, <b>this</b>);
        record.endEdit();
        <b>return</b> this;
    },

    <i>/**
     * Loads an Ext.data.Record into <b>this</b> form.
     * @param {Record} record The record to load
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    loadRecord : <b>function</b>(record){
        <b>this</b>.setValues(record.data);
        <b>return</b> this;
    },

    <i>// private</i>
    beforeAction : <b>function</b>(action){
        <b>var</b> o = action.options;
        <b>if</b>(o.waitMsg){
            <b>if</b>(this.waitMsgTarget === true){
                <b>this</b>.el.mask(o.waitMsg, <em>'x-mask-loading'</em>);
            }<b>else</b> if(<b>this</b>.waitMsgTarget){
                <b>this</b>.waitMsgTarget = Ext.get(<b>this</b>.waitMsgTarget);
                <b>this</b>.waitMsgTarget.mask(o.waitMsg, <em>'x-mask-loading'</em>);
            }<b>else</b>{
                Ext.MessageBox.wait(o.waitMsg, o.waitTitle || <b>this</b>.waitTitle || <em>'Please Wait...'</em>);
            }
        }
    },

    <i>// private</i>
    afterAction : <b>function</b>(action, success){
        <b>this</b>.activeAction = null;
        <b>var</b> o = action.options;
        <b>if</b>(o.waitMsg){
            <b>if</b>(this.waitMsgTarget === true){
                <b>this</b>.el.unmask();
            }<b>else</b> if(<b>this</b>.waitMsgTarget){
                <b>this</b>.waitMsgTarget.unmask();
            }<b>else</b>{
                Ext.MessageBox.updateProgress(1);
                Ext.MessageBox.hide();
            }
        }
        <b>if</b>(success){
            <b>if</b>(o.reset){
                <b>this</b>.reset();
            }
            Ext.callback(o.success, o.scope, [<b>this</b>, action]);
            <b>this</b>.fireEvent(<em>'actioncomplete'</em>, <b>this</b>, action);
        }<b>else</b>{
            Ext.callback(o.failure, o.scope, [<b>this</b>, action]);
            <b>this</b>.fireEvent(<em>'actionfailed'</em>, <b>this</b>, action);
        }
    },

    <i>/**
     * Find a Ext.form.Field <b>in</b> this form by id, dataIndex, name or hiddenName
     * @param {String} id The value to search <b>for</b>
     * @<b>return</b> Field
     */</i>
    findField : <b>function</b>(id){
        <b>var</b> field = <b>this</b>.items.get(id);
        <b>if</b>(!field){
            <b>this</b>.items.each(<b>function</b>(f){
                <b>if</b>(f.isFormField &amp;&amp; (f.dataIndex == id || f.id == id || f.getName() == id)){
                    field = f;
                    <b>return</b> false;
                }
            });
        }
        <b>return</b> field || null;
    },


    <i>/**
     * Mark fields <b>in</b> this form invalid <b>in</b> bulk.
     * @param {Array/Object} errors Either an array <b>in</b> the form [{id:<em>'fieldId'</em>, msg:<em>'The message'</em>},...] or an object hash of {id: msg, id2: msg2}
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    markInvalid : <b>function</b>(errors){
        <b>if</b>(errors instanceof Array){
            <b>for</b>(var i = 0, len = errors.length; i &lt; len; i++){
                <b>var</b> fieldError = errors[i];
                <b>var</b> f = <b>this</b>.findField(fieldError.id);
                <b>if</b>(f){
                    f.markInvalid(fieldError.msg);
                }
            }
        }<b>else</b>{
            <b>var</b> field, id;
            <b>for</b>(id <b>in</b> errors){
                <b>if</b>(typeof errors[id] != <em>'<b>function</b>'</em> &amp;&amp; (field = <b>this</b>.findField(id))){
                    field.markInvalid(errors[id]);
                }
            }
        }
        <b>return</b> this;
    },

    <i>/**
     * Set values <b>for</b> fields <b>in</b> this form <b>in</b> bulk.
     * @param {Array/Object} values Either an array <b>in</b> the form [{id:<em>'fieldId'</em>, value:<em>'foo'</em>},...] or an object hash of {id: value, id2: value2}
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    setValues : <b>function</b>(values){
        <b>if</b>(values instanceof Array){ <i>// array of objects</i>
            <b>for</b>(var i = 0, len = values.length; i &lt; len; i++){
                <b>var</b> v = values[i];
                <b>var</b> f = <b>this</b>.findField(v.id);
                <b>if</b>(f){
                    f.setValue(v.value);
                    <b>if</b>(this.trackResetOnLoad){
                        f.originalValue = f.getValue();
                    }
                }
            }
        }<b>else</b>{ <i>// object hash</i>
            <b>var</b> field, id;
            <b>for</b>(id <b>in</b> values){
                <b>if</b>(typeof values[id] != <em>'<b>function</b>'</em> &amp;&amp; (field = <b>this</b>.findField(id))){
                    field.setValue(values[id]);
                    <b>if</b>(this.trackResetOnLoad){
                        field.originalValue = field.getValue();
                    }
                }
            }
        }
        <b>return</b> this;
    },

    <i>/**
     * Returns the fields <b>in</b> this form as an object <b>with</b> key/value pairs. If multiple fields exist <b>with</b> the same name
     * they are returned as an array.
     * @param {Boolean} asString
     * @<b>return</b> {Object}
     */</i>
    getValues : <b>function</b>(asString){
        <b>var</b> fs = Ext.lib.Ajax.serializeForm(<b>this</b>.el.dom);
        <b>if</b>(asString === true){
            <b>return</b> fs;
        }
        <b>return</b> Ext.urlDecode(fs);
    },

    <i>/**
     * Clears all invalid messages <b>in</b> this form.
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    clearInvalid : <b>function</b>(){
        <b>this</b>.items.each(<b>function</b>(f){
           f.clearInvalid();
        });
        <b>return</b> this;
    },

    <i>/**
     * Resets <b>this</b> form.
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    reset : <b>function</b>(){
        <b>this</b>.items.each(<b>function</b>(f){
            f.reset();
        });
        <b>return</b> this;
    },

    <i>/**
     * Add Ext.form components to <b>this</b> form.
     * @param {Field} field1
     * @param {Field} field2 (optional)
     * @param {Field} etc (optional)
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    add : <b>function</b>(){
        <b>this</b>.items.addAll(Array.prototype.slice.call(arguments, 0));
        <b>return</b> this;
    },


    <i>/**
     * Removes a field from the items collection (does NOT remove its markup).
     * @param {Field} field
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    remove : <b>function</b>(field){
        <b>this</b>.items.remove(field);
        <b>return</b> this;
    },

    <i>/**
     * Looks at the fields <b>in</b> this form, checks them <b>for</b> an id attribute,
     * and calls applyTo on the existing dom element <b>with</b> that id.
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    render : <b>function</b>(){
        <b>this</b>.items.each(<b>function</b>(f){
            <b>if</b>(f.isFormField &amp;&amp; !f.rendered &amp;&amp; document.getElementById(f.id)){ <i>// <b>if</b> the element exists</i>
                f.applyTo(f.id);
            }
        });
        <b>return</b> this;
    },

    <i>/**
     * Calls {@link Ext#apply} <b>for</b> all fields <b>in</b> this form <b>with</b> the passed object.
     * @param {Object} values
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    applyToFields : <b>function</b>(o){
        <b>this</b>.items.each(<b>function</b>(f){
           Ext.apply(f, o);
        });
        <b>return</b> this;
    },

    <i>/**
     * Calls {@link Ext#applyIf} <b>for</b> all field <b>in</b> this form <b>with</b> the passed object.
     * @param {Object} values
     * @<b>return</b> {BasicForm} <b>this</b>
     */</i>
    applyIfToFields : <b>function</b>(o){
        <b>this</b>.items.each(<b>function</b>(f){
           Ext.applyIf(f, o);
        });
        <b>return</b> this;
    }
});

<i>// back compat</i>
Ext.BasicForm = Ext.form.BasicForm;</code></pre><hr><div style="font-size:10px;text-align:center;color:gray;">Ext - Copyright &copy; 2006-2007 Ext JS, LLC<br />All rights reserved.</div>
    </body></html>